package com.wanlian.dao.impl;

import com.wanlian.common.ConstantCode;
import com.wanlian.common.PageCondition;
import com.wanlian.common.UrlConfig;
import com.wanlian.context.Notice.NoticeMsgContext;
import com.wanlian.dao.NoticeMsgDao;
import com.wanlian.dao.UserDao;
import com.wanlian.entity.NoticeMsg;
import com.wanlian.entity.User;
import com.wanlian.error.SuccessCode;
import com.wanlian.jpush.service.PushService;
import com.wanlian.jpush.service.PushUtils;
import com.wanlian.jpush.service.YunPianSmsServices;
import com.wanlian.model.ResultModel;
import com.wanlian.util.StringUtil;
import com.wanlian.vo.NoticeMsgResultVo;
import com.wanlian.vo.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;


@Component
public class NoticeMsgDaoImpl extends GenericDaoImpl<NoticeMsg> implements NoticeMsgDao {
    @Autowired
    private PushService pushService;

    @Autowired
    private UserDao userDao;

    @Autowired
    private UrlConfig urlConfig;
    @Autowired
    private YunPianSmsServices yunPianSmsServices;

    public NoticeMsgDaoImpl() {
        super(NoticeMsg.class);
    }

    @Override
    public ResultModel sendMsgForOne(NoticeMsg noticeMsg) {
        ResultModel resultModel = new ResultModel();
        User user = userDao.queryById(noticeMsg.getUserId());
        if (ConstantCode.NOTICE_MSG_TYPE == noticeMsg.getNoticeType()) {
            noticeMsg.setSourceType(ConstantCode.NOTICE_NEWS);
            noticeMsg.setSendName(user.getUsername());
            addSingle(noticeMsg);
        } else {
            this.sendYunPian(user, noticeMsg.getTitle(), noticeMsg.getContent());
            noticeMsg.setSourceType(ConstantCode.NOTICE_MSG);
            noticeMsg.setSendName(user.getUsername());
            addSingleNoJpush(noticeMsg);
        }
        resultModel.setBresult(true);
        resultModel.setMessage(SuccessCode.NOTICE_SEND);
        resultModel.setObject(user.getUsername());
        return resultModel;
    }

    private boolean addSingleNoJpush(NoticeMsg model) {
        this.add(model);
        return true;
    }

    private boolean addSingle(NoticeMsg model) {
        this.add(model);
        User user = userDao.queryById(model.getUserId());
        NoticeMsgResultVo notice = new NoticeMsgResultVo();
        notice.setNoticeMsg(model);
        notice.setUser(user);
        NoticeMsgContext.add(notice);
        return true;
    }


    @Override
    public ResultModel sendMsgForMany(NoticeMsg noticeMsg) {
        ResultModel resultModel = new ResultModel();
        List<User> users = userDao.queryAll();
        if (0 == noticeMsg.getNoticeType()) {
            //发消息
            for (User user : users) {
                pushService.sendMessageBySingleTag(user.getPhone(), noticeMsg.getTitle(), noticeMsg.getContent());
                NoticeMsg noticeMsg1 = new NoticeMsg();

                noticeMsg1.setTitle(noticeMsg.getTitle());
                noticeMsg1.setContent(noticeMsg.getContent());
                noticeMsg1.setUrl(noticeMsg.getUrl());
                noticeMsg1.setAdmin(noticeMsg.getAdmin());

                noticeMsg1.setSendName(user.getUsername());
                noticeMsg1.setUserId(user.getId());
                noticeMsg1.setSourceType(ConstantCode.NOTICE_NEWS);
                this.add(noticeMsg1);
            }
        } else {
            //发短信
            for (User user : users) {
                this.sendYunPian(user, noticeMsg.getTitle(), noticeMsg.getContent());
                NoticeMsg noticeMsg1 = new NoticeMsg();

                noticeMsg1.setTitle(noticeMsg.getTitle());
                noticeMsg1.setContent(noticeMsg.getContent());
                noticeMsg1.setSendName(user.getUsername());
                noticeMsg1.setUserId(user.getId());
                noticeMsg1.setAdmin(noticeMsg.getAdmin());
                noticeMsg1.setSourceType(ConstantCode.NOTICE_MSG);
                noticeMsg1.setNoticeType(1);
                this.add(noticeMsg1);
            }
        }
        resultModel.setBresult(true);
        resultModel.setMessage(SuccessCode.NOTICE_SEND);
        return resultModel;
    }


    @Override
    public ResultModel queryNoticeMsgs(PageCondition pageCondition) {
        StringBuffer sqlWhere = new StringBuffer(" where 1 = 1");
        ArrayList<Object> params = new ArrayList<Object>();
        if (pageCondition.getConditions().containsKey("noticeType")) {
            String noticeType = (String) pageCondition.getByKey("noticeType");
            sqlWhere.append(" and ntype = ?");
            params.add(Integer.parseInt(noticeType));
        }
        if (pageCondition.isExistByKey("sourcetype")) {
            String sourcetype = (String) pageCondition.getConditions().get("sourcetype");
            if (StringUtil.hasValue(sourcetype)) {
                sqlWhere.append(" and sourcetype = ?");
                params.add(sourcetype);
            }
        }
        if (pageCondition.getConditions().containsKey("title")) {
            String title = (String) pageCondition.getByKey("title");
            if (title != null && title != "null" && title != "") {
                sqlWhere.append("and title like ?");
                params.add("%" + title + "%");
            }
        }
        if (pageCondition.getConditions().containsKey("admin")) {
            String admin = (String) pageCondition.getByKey("admin");
            if (admin != null && admin != "null" && admin != "") {
                sqlWhere.append(" and admin like ?");
                params.add("%" + admin + "%");
            }
        }
        if (pageCondition.getConditions().containsKey("startTime")) {
            String startTime = (String) pageCondition.getByKey("startTime");
            if (startTime != null && startTime != "") {
                sqlWhere.append(" and noticetime >= ?");
                Timestamp ts = Timestamp.valueOf(startTime + " 00:00:00.00");
                System.out.println(startTime);
                params.add(ts);
            }
        }
        if (pageCondition.getConditions().containsKey("endTime")) {
            String endTime = (String) pageCondition.getByKey("endTime");
            if (endTime != null && endTime != "") {
                sqlWhere.append(" and noticetime <= ?");
                Timestamp ts = Timestamp.valueOf(endTime + " 23:59:59.00");
                params.add(ts);
            }
        }
        List<NoticeMsg> noticeMsgList = this.queryForListByPage("from " + entityClassName() + sqlWhere + "order by noticetime desc", params.toArray(), pageCondition.getPage());
        String hql = String.format("select count(*) from %s " + sqlWhere, entityClassName());
        Long totalSize = this.queryCount(hql, params.toArray());
        ResultModel resultModel = new ResultModel(true);
        resultModel.setCount(totalSize);
        resultModel.setObject(noticeMsgList);
        return resultModel;
    }

    @Override
    public ResultModel queryCountByUserId(int userid) {
        StringBuffer sqlWhere = new StringBuffer(" where ntype = 0 and haslook = 0 and userid = ?");
        ArrayList<Object> params = new ArrayList<Object>();
        params.add(userid);
        String hql = String.format("select count(*) from %s " + sqlWhere, entityClassName());
        Long count = this.queryCount(hql, params.toArray());
        ResultModel resultModel = new ResultModel();
        resultModel.setCount(count);
        return resultModel;
    }

    @Override
    public ResultModel queryMsgByUserId(int userId, Page page) {
        StringBuffer sqlWhere = new StringBuffer(" where ntype = 0 and sourcetype != ? and userid =?");
        ArrayList<Object> params = new ArrayList<Object>();
        params.add(0, ConstantCode.NOTICE_SYSTEM);
        params.add(1, userId);
        List<NoticeMsg> noticeMsgList = this.queryForListByPage("from " + entityClassName() + sqlWhere + "order by noticetime desc", params.toArray(), page);
        String hql = String.format("select count(*) from %s " + sqlWhere, entityClassName());
        Long totalSize = this.queryCount(hql, params.toArray());
        ResultModel resultModel = new ResultModel(true);
        resultModel.setCount(totalSize);
        resultModel.setObject(noticeMsgList);
        return resultModel;
    }


    @Override
    public ResultModel updateHasLook(int noticeMsgId) {
        NoticeMsg noticeMsg = this.queryById(noticeMsgId);
        ResultModel resultModel = new ResultModel();
        if(noticeMsg==null){
            resultModel.setBresult(false);
            return  resultModel;
        }
        if (noticeMsg.isHasLook()) {
            resultModel.setBresult(false);
            resultModel.setMessage(SuccessCode.NOTICE_UPDATE_DEF);
        } else {
            noticeMsg.setHasLook(true);
            this.update(noticeMsg);
            resultModel.setBresult(true);
            resultModel.setMessage(SuccessCode.NOTICE_UPDATE_SUC);
        }
        return resultModel;
    }

    @Override
    public ResultModel querySystem(int userId, Page page) {
        StringBuffer sqlWhere = new StringBuffer(" where sourcetype = ? and userid = ? ");
        ArrayList<Object> params = new ArrayList<Object>();
        params.add(0, ConstantCode.NOTICE_SYSTEM);
        params.add(1, userId);
        List<NoticeMsg> noticeMsgList = this.queryForListByPage("from " + entityClassName() + sqlWhere + "order by noticetime desc", params.toArray(), page);
        String hql = String.format("select count(*) from %s " + sqlWhere, entityClassName());
        Long totalSize = this.queryCount(hql, params.toArray());
        ResultModel resultModel = new ResultModel(true);
        resultModel.setCount(totalSize);
        resultModel.setObject(noticeMsgList);
        return resultModel;
    }

    @Override
    public ResultModel queryCountSystem(int userId) {
        StringBuffer sqlWhere = new StringBuffer(" where haslook = 0 and sourcetype = ? and userid = ?");
        ArrayList<Object> params = new ArrayList<Object>();
        params.add(0, ConstantCode.NOTICE_SYSTEM);
        params.add(1, userId);
        String hql = String.format("select count(*) from %s " + sqlWhere, entityClassName());
        Long count = this.queryCount(hql, params.toArray());
        ResultModel resultModel = new ResultModel();
        resultModel.setCount(count);
        return resultModel;
    }

    @Override
    public ResultModel queryAllSystem(PageCondition pageCondition) {
        StringBuffer sqlWhere = new StringBuffer(" where sourcetype = ? ");
        ArrayList<Object> params = new ArrayList<Object>();
        params.add(ConstantCode.NOTICE_SYSTEM);
        if (pageCondition.getConditions().containsKey("title")) {
            String title = (String) pageCondition.getByKey("title");
            if (title != null && title != "null" && title != "") {
                sqlWhere.append("and title like ?");
                params.add("%" + title + "%");
            }
        }
        if (pageCondition.getConditions().containsKey("admin")) {
            String admin = (String) pageCondition.getByKey("admin");
            if (admin != null && admin != "null" && admin != "") {
                sqlWhere.append(" and admin like ?");
                params.add("%" + admin + "%");
            }
        }
        if (pageCondition.getConditions().containsKey("startTime")) {
            String startTime = (String) pageCondition.getByKey("startTime");
            if (startTime != null && startTime != "") {
                sqlWhere.append(" and noticetime >= ?");
                Timestamp ts = Timestamp.valueOf(startTime + " 00:00:00.00");
                params.add(ts);
            }
        }
        if (pageCondition.getConditions().containsKey("endTime")) {
            String endTime = (String) pageCondition.getByKey("endTime");
            if (endTime != null && endTime != "") {
                sqlWhere.append(" and noticetime <= ?");
                Timestamp ts = Timestamp.valueOf(endTime + " 23:59:59.00");
                params.add(ts);
            }
        }
        List<NoticeMsg> noticeMsgList = this.queryForListByPage("from " + entityClassName() + sqlWhere + "order by noticetime desc", params.toArray(), pageCondition.getPage());
        String hql = String.format("select count(*) from %s " + sqlWhere, entityClassName());
        Long totalSize = this.queryCount(hql, params.toArray());
        ResultModel resultModel = new ResultModel(true);
        resultModel.setCount(totalSize);
        resultModel.setObject(noticeMsgList);
        return resultModel;
    }

    @Override
    public List<NoticeMsg> queryAllByUserId(int userId) {
        StringBuffer sqlWhere = new StringBuffer(" noticeType = 0 and userid = ? ");
        ArrayList<Object> params = new ArrayList<Object>();
        params.add(userId);
        List<NoticeMsg> noticeMsgList = this.queryForListByWhere(sqlWhere.toString(), params.toArray());
        return noticeMsgList;
    }

    @Override
    public NoticeMsg queryNewSystemByUserId(int userId) {
        StringBuffer sqlWhere = new StringBuffer(" where ntype = 0 and sourcetype = ? and userid = ?");
        ArrayList<Object> params = new ArrayList<Object>();
        params.add(0, ConstantCode.NOTICE_SYSTEM);
        params.add(1, userId);
        List<NoticeMsg> noticeMsgList = this.queryForList("from " + entityClassName() + sqlWhere + " order by noticetime desc", params.toArray());
        if (noticeMsgList.size() > 0) {
            return noticeMsgList.get(0);
        }
        return null;
    }

    public void sendYunPian(User user, String title, String content) {
        try {
            String phone1 = URLEncoder.encode(user.getPhone(), urlConfig.getYunpianSmsEncoding());
            String content1 = "【MOC】verifycode:" + "t" + title + "co:" + content;
            yunPianSmsServices.sendSms(urlConfig.getYunpianSmsApiKey(), content1, phone1);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("unsupportedEncoding");
        } catch (IOException e) {
            throw new RuntimeException("IOException");
        }
    }
}
